package com.centaline.androidsalesblog.activities.mine;

import android.content.Intent;
import android.support.design.widget.TextInputLayout;
import android.support.v7.widget.AppCompatTextView;
import android.telephony.PhoneNumberFormattingTextWatcher;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.android.volley.VolleyError;
import com.centaline.androidsalesblog.R;
import com.centaline.androidsalesblog.api.usercenter.LoginApi;
import com.centaline.androidsalesblog.base.BaseLoginActivity;
import com.centaline.androidsalesblog.constants.AppConstant;
import com.centaline.androidsalesblog.constants.CommonConstant;
import com.centaline.androidsalesblog.events.UserOperate;
import com.centaline.androidsalesblog.events.WxStatus;
import com.centaline.androidsalesblog.model.databaseobject.UserDo;
import com.centaline.androidsalesblog.model.responseobject.SmsRo;
import com.centaline.androidsalesblog.model.responseobject.UserRo;
import com.centaline.androidsalesblog.model.responseobject.VerificationCodeRo;
import com.centaline.androidsalesblog.rx.database.RxDataBase;
import com.centaline.androidsalesblog.rx.request.RxRequest;
import com.centaline.androidsalesblog.utils.TextFormatUtil;
import com.centanet.framework.interfaces.IResponseListener;
import com.centanet.framework.utils.PatternFormat;
import com.jakewharton.rxbinding.view.RxView;
import com.jakewharton.rxbinding.widget.RxTextView;
import com.trello.rxlifecycle.ActivityEvent;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func2;
import rx.schedulers.Schedulers;

/**
 * 无密码快捷登录
 * <p/>
 * Created by fusl1 on 2015/12/22.
 * Modify by Lihq on 2016/01/12.
 */
public class LoginActivity extends BaseLoginActivity implements View.OnClickListener {

    private TextInputLayout til_phone;
    private TextInputLayout til_verification;
    private Button btn_verification_code;
    private Button btn_login;
    private AppCompatTextView atv_login_other;
    private EditText phoneEditText, verificationEditText;

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Override
    protected int setLayoutId() {
        return R.layout.activity_login;
    }

    @Override
    protected void findViews() {
        til_phone = (TextInputLayout) findViewById(R.id.til_phone);
        til_verification = (TextInputLayout) findViewById(R.id.til_verification);
        btn_verification_code = (Button) findViewById(R.id.btn_verification_code);
        btn_login = (Button) findViewById(R.id.btn_login);
        atv_login_other = (AppCompatTextView) findViewById(R.id.atv_login_other);
        EventBus.getDefault().register(this);
    }

    @Override
    protected void initViews() {
        setUniversalToolbar(R.string.title_login_sms);
        if (getSupportActionBar() != null) {
            getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_clear_white);
        }
        phoneEditText = til_phone.getEditText();
        verificationEditText = til_verification.getEditText();
        if (phoneEditText != null &&
                verificationEditText != null) {
            Observable<CharSequence> phoneChangeObservable = RxTextView.textChanges(phoneEditText).skip(1);
            Observable<CharSequence> verificationChangeObservable = RxTextView.textChanges(verificationEditText).skip(1);

            phoneEditText.addTextChangedListener(new PhoneNumberFormattingTextWatcher());

            phoneChangeObservable.
                    compose(this.<CharSequence>bindUntilEvent(ActivityEvent.DESTROY))
                    .subscribe(new Action1<CharSequence>() {
                        @Override
                        public void call(CharSequence charSequence) {
                            Pattern pattern = Pattern.compile(PatternFormat.PhoneNumber);
                            Matcher matcher = pattern.matcher(charSequence);
                            boolean phoneValid = matcher.find();
                            btn_verification_code.setEnabled(phoneValid);
                            if (phoneValid) {
                                til_phone.setError(null);
                            } else if (til_phone.getError() == null) {
                                til_phone.setError(getString(R.string.error_phone));
                            }
                        }
                    });

            verificationChangeObservable.
                    compose(this.<CharSequence>bindUntilEvent(ActivityEvent.DESTROY))
                    .subscribe(new Action1<CharSequence>() {
                        @Override
                        public void call(CharSequence charSequence) {
                            final boolean verificationValid = charSequence.length() > 5;
                            if (verificationValid) {
                                til_verification.setError(null);
                            } else if (til_verification.getError() == null) {
                                til_verification.setError(getString(R.string.error_verification));
                            }
                        }
                    });

            Observable.combineLatest(phoneChangeObservable, verificationChangeObservable,
                    new Func2<CharSequence, CharSequence, Boolean>() {
                        @Override
                        public Boolean call(CharSequence phoneNumber, CharSequence verificationCode) {
                            Pattern pattern = Pattern.compile(PatternFormat.PhoneNumber);
                            Matcher matcher = pattern.matcher(phoneNumber);
                            boolean phoneValid = matcher.find();
                            final boolean verificationValid = verificationCode.length() > 5;
                            return phoneValid && verificationValid;
                        }
                    })
                    .compose(this.<Boolean>bindUntilEvent(ActivityEvent.DESTROY))
                    .subscribe(new Action1<Boolean>() {
                        @Override
                        public void call(Boolean aBoolean) {
                            btn_login.setEnabled(aBoolean);
                        }
                    });
        }

        RxView.clicks(btn_verification_code)
                .throttleFirst(1, TimeUnit.SECONDS)
                .compose(this.<Void>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        smsCode();
                    }
                });

        RxView.clicks(btn_login)
                .throttleFirst(1, TimeUnit.SECONDS)
                .compose(this.<Void>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        checkSmsCode();
                    }
                });

        RxView.clicks(atv_login_other)
                .throttleFirst(1, TimeUnit.SECONDS)
                .compose(this.<Void>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        startActivityForResult(new Intent(LoginActivity.this, CentalineLoginActivity.class),
                                CommonConstant.REQ_LOGIN);
                        baiduEvent("O1_2_Click");
                    }
                });
    }

    /**
     * 倒计时
     */
    private void verification() {
        btn_verification_code.setClickable(false);
        Observable.interval(0, 1, TimeUnit.SECONDS).take(61)
                .compose(this.<Long>bindUntilEvent(ActivityEvent.DESTROY))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        final long remain = 60 - aLong;
                        if (remain > 0) {
                            btn_verification_code.setText(String.format(Locale.CHINA, "%d秒后重新获取", 60 - aLong));
                        } else {
                            btn_verification_code.setClickable(true);
                            btn_verification_code.setText(getString(R.string.get_verification_code));
                        }
                    }
                });
    }

    /**
     * 获取验证码
     */
    private void smsCode() {
        RxRequest.sms(LoginActivity.class, TextFormatUtil.formatPhoneNumber(phoneEditText))
                .compose(this.<SmsRo>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Action1<SmsRo>() {
                    @Override
                    public void call(SmsRo smsRo) {
                        if (0 == smsRo.getResultNo()) {
                            verification();
                            toast("验证码将发送到您的手机上");
                        } else {
                            toast(smsRo.getMessage());
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        netWorkUnable();
                    }
                });
    }

    /**
     * 检查验证码
     */
    private void checkSmsCode() {
        hideKeyboard(til_phone);
        showLoadingDialog();
        RxRequest.VerificationCode(LoginActivity.class,
                TextFormatUtil.formatPhoneNumber(phoneEditText),
                verificationEditText.getText().toString())
                .compose(this.<VerificationCodeRo>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Action1<VerificationCodeRo>() {
                    @Override
                    public void call(VerificationCodeRo verificationCodeRo) {
                        if (verificationCodeRo.getResultNo() == 0) {
                            login();
                        } else {
                            cancelLoadingDialog();
                            snack("请确认您的验证码是否输入正确");
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        netWorkUnable();
                    }
                });
    }

    /**
     * 登录
     */
    private void login() {
        LoginApi loginApi = new LoginApi(LoginActivity.class, UserRo.class, new IResponseListener<UserRo>() {
            @Override
            public void onResponse(UserRo userRo) {
                UserDo userDo = userRo.getUserDo();
                int resultNo = userRo.getResultNo();
                switch (resultNo) {
                    case 0:
                        AppConstant.setUserLogin(LoginActivity.this, userDo);
                        userSave(userDo);
                        break;
                    default:
                        cancelLoadingDialog();
                        snack(userRo.getMessage());
                        break;
                }
            }

            @Override
            public void onErrorResponse(VolleyError error) {
                netWorkUnable();
            }
        });
        loginApi.setPhone(TextFormatUtil.formatPhoneNumber(phoneEditText));
        loginApi.setVerificationCode(verificationEditText.getText().toString());
        loginApi.startRequest();
    }

    /**
     * 保存用户信息
     */
    private void userSave(UserDo userDo) {
        AppConstant.setUserLogin(this, userDo);
        RxDataBase.saveUser(userDo)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(this.<Boolean>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Action1<Boolean>() {
                    @Override
                    public void call(Boolean aBoolean) {
                        cancelLoadingDialog();
                        loginSuccess();
                    }
                });
    }


    /**
     * 登录成功
     */
    private void loginSuccess() {
        EventBus.getDefault().post(new UserOperate(1));
        setResult(RESULT_OK);
        finish();
    }

    @Override
    protected void otherLoginSuccess() {
        super.otherLoginSuccess();
        loginSuccess();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.img_login_wechat:
                loginWx = true;
                wXLogin();
                baiduEvent("O1_3_Type", "微信");
                break;
            case R.id.img_login_qq:
                qqLogin();
                baiduEvent("O1_3_Type", "QQ");
                break;
            case R.id.img_login_weibo:
                sinaLogin();
                baiduEvent("O1_3_Type", "sina");
                break;
            default:
                break;
        }
    }

    /**
     * 用户状态改变
     */
    @Subscribe
    public void onEventMainThread(WxStatus wxStatus) {
        if (loginWx) {
            switch (wxStatus.getStatus()) {
                case 0:
                    requestWxAuth(wxStatus.getCode());
                    break;
                case 1:
                    userCancel();
                    break;
                default:
                    break;
            }
        }
        loginWx = false;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.menu_login, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.register) {
            startActivityForResult(new Intent(this, RegisterActivity.class), CommonConstant.REQ_LOGIN);
            baiduEvent("O1_1_Click");
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case CommonConstant.REQ_LOGIN:
                    //登录成功
                    loginSuccess();
                    break;
                default:
                    break;
            }
        }
    }
}
